/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bgu.ppm.dat.view;

import bgu.ppm.dat.model.Table;
import bgu.sonar.util.evt.EventListeners;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetChangeListener;
import org.jfree.data.general.DatasetGroup;

/**
 *
 * @author User
 */
public class FastCategoryDataset implements CategoryDataset {
    public static final int MAX_RECORDS = 10000;
    
    private final Table data;
    private Map<String, Integer> keysIndexLookup;
    private EventListeners<DatasetChangeListener> listeners = EventListeners.create(DatasetChangeListener.class);

    public FastCategoryDataset(Table data) {
        this.data = data;
        
        if (data.getColumnHeaders().length > MAX_RECORDS || data.getRowHeaders().length > MAX_RECORDS) {
            throw new UnsupportedOperationException("Could not generate graph for more than " + MAX_RECORDS + " records.");
        }

        keysIndexLookup = new HashMap<>();
        for (int i = 0; i < data.getRowHeaders().length; i++) {
            keysIndexLookup.put("ROW_" + DatasetUtils.join(data.getRowHeaders()[i], " "), i);
        }
        for (int i = 0; i < data.getColumnHeaders().length; i++) {
            keysIndexLookup.put("COL_" + DatasetUtils.join(data.getColumnHeaders()[i], " "), i);
        }
        
        //System.out.println("lookup: " + keysIndexLookup);
    }

    @Override
    public Comparable getColumnKey(int i) {
        return DatasetUtils.join(data.getRowHeaders()[i], " ");
    }

    @Override
    public int getColumnIndex(Comparable cmprbl) {
        return keysIndexLookup.get("ROW_" + cmprbl);
    }

    @Override
    public List getColumnKeys() {
        LinkedList<String> result = new LinkedList<>();
        for (Integer i = 0; i < data.getRowHeaders().length; i++) {
            result.add(DatasetUtils.join(data.getRowHeaders()[i], " "));
        }

        return result;
    }

    @Override
    public Comparable getRowKey(int i) {
        return DatasetUtils.join(data.getColumnHeaders()[i], " ");
    }

    @Override
    public int getRowIndex(Comparable cmprbl) {
        Integer result = keysIndexLookup.get("COL_" + cmprbl);
        if (result == null) {
            throw new RuntimeException("could not found column " + cmprbl);
        }

        return result;
    }

    @Override
    public List getRowKeys() {
        LinkedList<String> result = new LinkedList<>();
        for (Integer i = 0; i < data.getColumnHeaders().length; i++) {
            result.add(DatasetUtils.join(data.getColumnHeaders()[i], " "));
        }

        return result;
    }

    @Override
    public Number getValue(Comparable cmprbl, Comparable cmprbl1) {
        return (Number) data.getCell(getColumnIndex(cmprbl), getRowIndex(cmprbl1));
    }

    @Override
    public int getRowCount() {
        return data.getColumnHeaders().length;
    }

    @Override
    public int getColumnCount() {
        return data.getRowHeaders().length;
    }

    @Override
    public Number getValue(int i, int i1) {
        return (Number) data.getCell(i, i1);
    }

    @Override
    public void addChangeListener(DatasetChangeListener dl) {
        listeners.add(dl);
    }

    @Override
    public void removeChangeListener(DatasetChangeListener dl) {
        listeners.remove(dl);
    }

    @Override
    public DatasetGroup getGroup() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void setGroup(DatasetGroup dg) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }    
}
